ensure no crash due to uncatched exception from std c++ lib
authorMatthieu Gallien <matthieu.gallien@nextcloud.com>
Wed, 18 Dec 2024 11:36:05 +0000 (12:36 +0100)
committerMatthieu Gallien <matthieu.gallien@nextcloud.com>
Thu, 2 Jan 2025 09:20:27 +0000 (10:20 +0100)
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
src/common/filesystembase.cpp
src/libsync/filesystem.cpp
src/libsync/owncloudpropagator.cpp
src/libsync/propagatedownload.cpp
src/libsync/propagatorjobs.cpp
test/testsyncengine.cpp

index af9e19cb65bd1aae126555e36ac5efe54389671d..cf806fd8e83765c7f2561ae3275d13a92f76d596 100644 (file)
@@ -127,11 +127,11 @@ void FileSystem::setFileReadOnly(const QString &filename, bool readonly)
                 std::filesystem::permissions(filename.toStdString(), defaultWritePermissions, std::filesystem::perm_options::add);
             }
         }
-        catch (std::filesystem::filesystem_error e)
+        catch (const std::filesystem::filesystem_error &e)
         {
             qCWarning(lcFileSystem()) << filename << (readonly ? "readonly" : "read write") << e.what();
         }
-        catch (std::system_error e)
+        catch (const std::system_error &e)
         {
             qCWarning(lcFileSystem()) << filename << e.what();
         }
@@ -180,11 +180,11 @@ bool FileSystem::setFileReadOnlyWeak(const QString &filename, bool readonly)
             setFileReadOnly(filename, readonly);
             return true;
         }
-        catch (std::filesystem::filesystem_error e)
+        catch (const std::filesystem::filesystem_error &e)
         {
             qCWarning(lcFileSystem()) << filename << (readonly ? "readonly" : "read write") << e.what();
         }
-        catch (std::system_error e)
+        catch (const std::system_error &e)
         {
             qCWarning(lcFileSystem()) << filename << e.what();
         }
@@ -480,11 +480,11 @@ bool FileSystem::isWritable(const QString &filename, const QFileInfo &fileInfo)
             const auto permissions = filePermissionsWin(filename);
             return static_cast<bool>((permissions & std::filesystem::perms::owner_write));
         }
-        catch (std::filesystem::filesystem_error e)
+        catch (const std::filesystem::filesystem_error &e)
         {
             qCWarning(lcFileSystem()) << filename << e.what();
         }
-        catch (std::system_error e)
+        catch (const std::system_error &e)
         {
             qCWarning(lcFileSystem()) << filename << e.what();
         }
@@ -514,11 +514,11 @@ bool FileSystem::isReadable(const QString &filename, const QFileInfo &fileInfo)
             const auto permissions = filePermissionsWin(filename);
             return static_cast<bool>((permissions & std::filesystem::perms::owner_read));
         }
-        catch (std::filesystem::filesystem_error e)
+        catch (const std::filesystem::filesystem_error &e)
         {
             qCWarning(lcFileSystem()) << filename << e.what();
         }
-        catch (std::system_error e)
+        catch (const std::system_error &e)
         {
             qCWarning(lcFileSystem()) << filename << e.what();
         }
index 9dbdde6a7474ca69c97440ffbf91ec3e89286037..2f288b85fe5bd37af7373560882da3c48008d77c 100644 (file)
@@ -332,7 +332,8 @@ bool FileSystem::setFolderPermissions(const QString &path,
 {
     static constexpr auto writePerms = std::filesystem::perms::owner_write | std::filesystem::perms::group_write | std::filesystem::perms::others_write;
     const auto stdStrPath = path.toStdWString();
-    try {
+    try
+    {
         switch (permissions) {
         case OCC::FileSystem::FolderPermissions::ReadOnly:
             std::filesystem::permissions(stdStrPath, writePerms, std::filesystem::perm_options::remove);
@@ -340,10 +341,22 @@ bool FileSystem::setFolderPermissions(const QString &path,
         case OCC::FileSystem::FolderPermissions::ReadWrite:
             break;
         }
-    } catch (const std::filesystem::filesystem_error &e) {
+    }
+    catch (const std::filesystem::filesystem_error &e)
+    {
         qCWarning(lcFileSystem()) << "exception when modifying folder permissions" << e.what() << e.path1().c_str() << e.path2().c_str();
         return false;
     }
+    catch (const std::system_error &e)
+    {
+        qCWarning(lcFileSystem()) << "exception when modifying folder permissions" << e.what();
+        return false;
+    }
+    catch (...)
+    {
+        qCWarning(lcFileSystem()) << "exception when modifying folder permissions";
+        return false;
+    }
 
 #ifdef Q_OS_WIN
     SECURITY_INFORMATION info = DACL_SECURITY_INFORMATION;
@@ -463,7 +476,8 @@ bool FileSystem::setFolderPermissions(const QString &path,
     }
 #endif
 
-    try {
+    try
+    {
         switch (permissions) {
         case OCC::FileSystem::FolderPermissions::ReadOnly:
             break;
@@ -472,17 +486,30 @@ bool FileSystem::setFolderPermissions(const QString &path,
             std::filesystem::permissions(stdStrPath, std::filesystem::perms::owner_write, std::filesystem::perm_options::add);
             break;
         }
-    } catch (const std::filesystem::filesystem_error &e) {
+    }
+    catch (const std::filesystem::filesystem_error &e)
+    {
         qCWarning(lcFileSystem()) << "exception when modifying folder permissions" << e.what() << e.path1().c_str() << e.path2().c_str();
         return false;
     }
+    catch (const std::system_error &e)
+    {
+        qCWarning(lcFileSystem()) << "exception when modifying folder permissions" << e.what();
+        return false;
+    }
+    catch (...)
+    {
+        qCWarning(lcFileSystem()) << "exception when modifying folder permissions";
+        return false;
+    }
 
     return true;
 }
 
 bool FileSystem::isFolderReadOnly(const std::filesystem::path &path) noexcept
 {
-    try {
+    try
+    {
         const auto folderStatus = std::filesystem::status(path);
         const auto folderPermissions = folderStatus.permissions();
         return (folderPermissions & std::filesystem::perms::owner_write) != std::filesystem::perms::owner_write;
@@ -492,21 +519,42 @@ bool FileSystem::isFolderReadOnly(const std::filesystem::path &path) noexcept
         qCWarning(lcFileSystem()) << "exception when checking folder permissions" << e.what() << e.path1().c_str() << e.path2().c_str();
         return false;
     }
+    catch (const std::system_error &e)
+    {
+        qCWarning(lcFileSystem()) << "exception when checking folder permissions" << e.what();
+        return false;
+    }
+    catch (...)
+    {
+        qCWarning(lcFileSystem()) << "exception when checking folder permissions";
+        return false;
+    }
 }
 
 FileSystem::FilePermissionsRestore::FilePermissionsRestore(const QString &path, FolderPermissions temporaryPermissions)
     : _path(path)
 {
-    try {
+    try
+    {
         const auto stdStrPath = _path.toStdWString();
         _initialPermissions = FileSystem::isFolderReadOnly(stdStrPath) ? OCC::FileSystem::FolderPermissions::ReadOnly : OCC::FileSystem::FolderPermissions::ReadWrite;
         if (_initialPermissions != temporaryPermissions) {
             _rollbackNeeded = true;
             FileSystem::setFolderPermissions(_path, temporaryPermissions);
         }
-    } catch (const std::filesystem::filesystem_error &e) {
+    }
+    catch (const std::filesystem::filesystem_error &e)
+    {
         qCWarning(lcFileSystem()) << "exception when modifying folder permissions" << e.what() << e.path1().c_str() << e.path2().c_str();
     }
+    catch (const std::system_error &e)
+    {
+        qCWarning(lcFileSystem()) << "exception when modifying folder permissions" << e.what();
+    }
+    catch (...)
+    {
+        qCWarning(lcFileSystem()) << "exception when modifying folder permissions";
+    }
 }
 
 FileSystem::FilePermissionsRestore::~FilePermissionsRestore()
index dac9a0e608cbede5d82e186a598fd4ab9e550424..cce9522129b45301f8591754419a2b0243cfb371 100644 (file)
@@ -1472,6 +1472,18 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
                     _item->_status = SyncFileItem::NormalError;
                     _item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, e.what());
                 }
+                catch (const std::system_error &e)
+                {
+                    qCWarning(lcDirectory) << "exception when checking parent folder access rights" << e.what();
+                    _item->_status = SyncFileItem::NormalError;
+                    _item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, e.what());
+                }
+                catch (...)
+                {
+                    qCWarning(lcDirectory) << "exception when checking parent folder access rights";
+                    _item->_status = SyncFileItem::NormalError;
+                    _item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, tr("unknown exception"));
+                }
             } else {
                 try {
                     const auto permissionsChangeHelper = [] (const auto fileName)
@@ -1494,6 +1506,18 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
                     _item->_status = SyncFileItem::NormalError;
                     _item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg(e.path1().c_str(), e.what());
                 }
+                catch (const std::system_error &e)
+                {
+                    qCWarning(lcDirectory) << "exception when checking parent folder access rights" << e.what();
+                    _item->_status = SyncFileItem::NormalError;
+                    _item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg("", e.what());
+                }
+                catch (...)
+                {
+                    qCWarning(lcDirectory) << "exception when checking parent folder access rights";
+                    _item->_status = SyncFileItem::NormalError;
+                    _item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg("", tr("unknown exception"));
+                }
             }
 #endif
             if (!_item->_isAnyCaseClashChild && !_item->_isAnyInvalidCharChild) {
index 3bcfd237316dcf26c023846cf72fced951522633..39108e4e113d46bc8353ff2fa06503f707180392 100644 (file)
@@ -690,6 +690,14 @@ void PropagateDownloadFile::startDownload()
     {
         qCWarning(lcPropagateDownload) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
     }
+    catch (const std::system_error &e)
+    {
+        qCWarning(lcPropagateDownload) << "exception when checking parent folder access rights" << e.what();
+    }
+    catch (...)
+    {
+        qCWarning(lcPropagateDownload) << "exception when checking parent folder access rights";
+    }
 
     if (FileSystem::isFolderReadOnly(_parentPath)) {
         FileSystem::setFolderPermissions(QString::fromStdWString(_parentPath.wstring()), FileSystem::FolderPermissions::ReadWrite);
@@ -1219,11 +1227,11 @@ void PropagateDownloadFile::downloadFinished()
                 FileSystem::setFilePermissionsWin(_tmpFile.fileName(), existingPermissions);
             }
         }
-        catch (std::filesystem::filesystem_error e)
+        catch (const std::filesystem::filesystem_error &e)
         {
             qCWarning(lcPropagateDownload()) << _item->_instruction << _item->_file << e.what();
         }
-        catch (std::system_error e)
+        catch (const std::system_error &e)
         {
             qCWarning(lcPropagateDownload()) << _item->_instruction << _item->_file << e.what();
         }
index 746e29e79eac308a122db866cab779578aacf298..6d1bb1b6fddcf2ca1595d441d1a9c3f66b1387df 100644 (file)
@@ -217,6 +217,14 @@ void PropagateLocalMkdir::startLocalMkdir()
     {
         qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
     }
+    catch (const std::system_error &e)
+    {
+        qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights" << e.what();
+    }
+    catch (...)
+    {
+        qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights";
+    }
 #endif
 
     emit propagator()->touchedFile(newDirStr);
@@ -239,6 +247,18 @@ void PropagateLocalMkdir::startLocalMkdir()
             done(SyncFileItem::NormalError, tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, e.what()), ErrorCategory::GenericError);
             return;
         }
+        catch (const std::system_error &e)
+        {
+            qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights" << e.what();
+            done(SyncFileItem::NormalError, tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, e.what()), ErrorCategory::GenericError);
+            return;
+        }
+        catch (...)
+        {
+            qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights";
+            done(SyncFileItem::NormalError, tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, tr("unknown exception")), ErrorCategory::GenericError);
+            return;
+        }
     }
 
     try {
@@ -251,6 +271,14 @@ void PropagateLocalMkdir::startLocalMkdir()
     {
         qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
     }
+    catch (const std::system_error &e)
+    {
+        qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights" << e.what();
+    }
+    catch (...)
+    {
+        qCWarning(lcPropagateLocalMkdir) << "exception when checking parent folder access rights";
+    }
 #endif
 
     // Insert the directory into the database. The correct etag will be set later,
@@ -349,6 +377,14 @@ void PropagateLocalRename::start()
         {
             qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
         }
+        catch (const std::system_error &e)
+        {
+            qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights" << e.what();
+        }
+        catch (...)
+        {
+            qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights";
+        }
 
         auto originParentFolderPath = std::filesystem::path{};
         auto originParentFolderWasReadOnly = false;
@@ -366,6 +402,14 @@ void PropagateLocalRename::start()
         {
             qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
         }
+        catch (const std::system_error &e)
+        {
+            qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights" << e.what();
+        }
+        catch (...)
+        {
+            qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights";
+        }
 
         const auto restoreTargetPermissions = [this] (const auto &parentFolderPath) {
             try {
@@ -376,6 +420,14 @@ void PropagateLocalRename::start()
             {
                 qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
             }
+            catch (const std::system_error &e)
+            {
+                qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights" << e.what();
+            }
+            catch (...)
+            {
+                qCWarning(lcPropagateLocalRename) << "exception when checking parent folder access rights";
+            }
         };
 
         const auto folderPermissionsHandler = FileSystem::FilePermissionsRestore{existingFile, FileSystem::FolderPermissions::ReadWrite};
index 079dd18c1f943ec32c5236467bc906e86d8acc7d..8c11104cabd2147903ec99013a22de6997115305 100644 (file)
@@ -860,6 +860,14 @@ private slots:
         {
             qCritical() << e.what() << e.path1().c_str() << e.path2().c_str() << e.code().message().c_str();
         }
+        catch (const std::system_error &e)
+        {
+            qCritical() << e.what() << e.code().message().c_str();
+        }
+        catch (...)
+        {
+            qCritical() << "exception unknown";
+        }
         QTextCodec::setCodecForLocale(utf8Locale);
 #endif
     }